home *** CD-ROM | disk | FTP | other *** search
/ The Original Shareware 1.1 / The Original Shareware (WeMake CDs)(Volume 1.1)(CDs, Inc)(1993).iso / 19 / genindex.zip / GENINDEX.PAS
Pascal/Delphi Source File  |  1987-11-08  |  11KB  |  436 lines

  1. {$S+}{}
  2. program index(input,output) ;
  3.  
  4.   This PASCAL MT+ index generator program is placed in
  5.   the public domain on the understanding that it is for
  6.   non-profit redistribution via individuals for through
  7.   RCPM systems
  8.   Donated 23/6/83
  9.   Matthew Starr P.O. Box 25 Wahroonga N.S.W 2076
  10.         Australia
  11.  
  12.   Matthew Starr 13/12/81
  13.  
  14.   WordStar index generator program which will
  15.   read through WordStar disk file output files
  16.   and include strings delimited by ^Q and ^W as
  17.   Major and Minor references respectively, creating
  18.   an index which is then sorted and output as a
  19.   WordStar source file.
  20.  
  21.   A required option for the Disk-file print is
  22.   form feed page separation. (See procedure HELP)
  23. }
  24.  
  25. const
  26.     main_code = 17 ;        {code for boldface ref}
  27.     sub_code = 23 ;        {code for normal ref}
  28.     bold_code = 2 ;        {makes it boldface}
  29.     formfeed = 12 ;
  30.     stringz = 50 ;        {P.S. also change assgmnt}
  31.     max_entries = 500 ;        {max # different entries}
  32.     max_refs = 5 ;        {max # refs of either type}
  33.  
  34.  
  35. type
  36.     my_string = packed array[1 .. stringz] of char ;
  37.     pointer = ^entry_type ;
  38.     entry_type =
  39.     record
  40.         subject : my_string ;
  41.         n_mains : integer ;
  42.         mains : array[1 .. max_refs] of integer ;
  43.         n_subs : integer ;
  44.         subs : array[1 .. max_refs] of integer ;
  45.     end ; { entry decl. }
  46.     table_type = array[1 .. maxentries] of pointer ;
  47.  
  48.     ws_file = file of char ;
  49.     index_file = file of entry_type ;
  50.  
  51.  
  52. var
  53.     index : index_file ;
  54.     text_in : ws_file ;
  55.     text_out : text ;
  56.  
  57.     end_file : entry_type ;
  58.     table : table_type ;
  59.     filename,response : string ;
  60.     i, num_entries, result : integer ;
  61.  
  62.  
  63. procedure addentry(var table:table_type; var tablength:integer; newentry:entry_type) ;
  64.  
  65.     begin
  66.     if tablength >= max_entries
  67.         then writeln('Too many entries - entry table full')
  68.         else
  69.         begin
  70.             tablength := tablength+1 ;
  71.             new(table[tablength]) ;
  72.             table[tablength]^ := newentry
  73.         end { else there is room }
  74.     end;
  75.  
  76.  
  77. procedure readarray(var name:my_string) ;
  78.  
  79.     var
  80.     ch : char;
  81.     nameindex : 0 .. stringz;
  82.  
  83.     procedure uppercase(var ch:char) ;
  84.     begin
  85.         if ord(ch)>127
  86.         then ch := chr( ord(ch) - 128 ) ;
  87.         if (ch >= 'a') and (ch <='z')
  88.         then ch := chr( ord(ch)-(ord('a')-ord('A')) );
  89.     end ; {uppercase}
  90.  
  91.     begin
  92.     name := '                                                  ' ;
  93.     nameindex := 0 ;
  94.     read(text_in,ch) ;
  95.     uppercase(ch) ;
  96.     while (name_index<stringz)
  97.         and (ord(ch)<>main_code) and (ord(ch)<>sub_code) do
  98.         begin
  99.         nameindex := nameindex+1 ;
  100.         name[nameindex] := ch ;
  101.         read(text_in,ch) ;
  102.         uppercase(ch)
  103. { and throw away terminating control code }
  104.         end {while}
  105.     end ; {readarray}
  106.  
  107.  
  108. procedure get_main
  109. (var table:tabletype; var tablength:integer; var page, created, added_to:integer);
  110.  
  111.     var
  112.     name: my_string;
  113.     this_entry: entry_type;
  114.     i: integer;
  115.  
  116.     begin
  117.     readarray(name);
  118.     i := 1 ;
  119.     while (i<=num_entries) and (name<>table[i]^.subject) do
  120.         i:=i+1 ;
  121.     if i>num_entries    { i.e. if not found }
  122.  
  123.         then
  124.         begin { create a new entry }
  125.             with this_entry do
  126.             begin
  127.                 created := created + 1 ;
  128.                 subject := name ;
  129.                 n_mains := 1 ;
  130.                 n_subs := 0 ;
  131.                 mains[1] := page
  132.             end { with } ;
  133.             addentry(table,tablength,this_entry)
  134.         end {then}
  135.  
  136.         else {add to the ith entry}
  137.         with table[i]^ do
  138.             begin
  139.             added_to := added_to + 1 ;
  140.             if n_mains >= max_refs
  141.                 then
  142.                 writeln('Too many main references to ',subject)
  143.                 else
  144.                 begin
  145.                     n_mains := n_mains+1 ;
  146.                     mains[n_mains] := page
  147.                 end {else}
  148.             end {with}
  149.     end ; {get_main}
  150.  
  151.  
  152. procedure get_sub
  153. (var table:tabletype; var tablength:integer; var page, created, added_to:integer);
  154.  
  155.     var
  156.     name: my_string;
  157.     this_entry: entry_type;
  158.     i: integer;
  159.  
  160.     begin
  161.     readarray(name);
  162.     i := 1 ;
  163.     while (i<=num_entries) and (name<>table[i]^.subject) do
  164.         i:=i+1 ;
  165.  
  166.     if i>num_entries    {i.e. was it found ?}
  167.         then
  168.         begin        { create a new entry }
  169.             with this_entry do
  170.             begin
  171.                 created := created + 1 ;
  172.                 subject := name ;
  173.                 n_mains := 0 ;
  174.                 n_subs := 1 ;
  175.                 subs[1] := page ;
  176.             end { with } ;
  177.             addentry(table,tablength,this_entry)
  178.         end {then}
  179.  
  180.         else
  181.         with table[i]^ do
  182.             begin
  183.             added_to := added_to + 1 ;
  184.             if n_subs >= max_refs
  185.                 then
  186.                 writeln('Too many minor references to ',subject)
  187.                 else
  188.                 begin
  189.                     n_subs := n_subs+1 ;
  190.                     subs[n_subs] := page
  191.                 end {else}
  192.             end {with}
  193.     end ; {get_sub}
  194.  
  195.  
  196. procedure scanfile
  197. (var table:tabletype; var tablength:integer; filename:string);
  198.  
  199. var
  200.     ch:char ;
  201.     page, created, added_to : integer ;
  202.  
  203.     begin
  204.     created := 0 ;
  205.     added_to := 0 ;
  206.     assign(text_in,filename) ;
  207.     reset(text_in) ;
  208.     if ioresult = 255
  209.         then writeln('Could not open ',filename)
  210.         else
  211.         begin
  212.             write('Page number start for this file? ');
  213.             read(page) ;
  214.             while not eof(text_in) do
  215.             begin
  216.                 read(text_in,ch) ;
  217.                 if ord(ch)=formfeed
  218.                 then page := page + 1
  219.                 else if ord(ch)=main_code
  220.                 then get_main(table,tablength,page, created, added_to)
  221.                 else if ord(ch)=sub_code
  222.                 then get_sub(table,tablength,page, created, added_to)
  223.             end ;
  224.             writeln(created,' new entries created');
  225.             writeln(added_to,' references added to existing subjects.')
  226.         end { else file opened successfully }
  227.     end ; { scanfile }
  228.  
  229.  
  230. function lessthan(el1,el2 : pointer) : boolean ;
  231. {compare the two entries as per ascii}
  232.  
  233.     begin
  234.     lessthan := el1^.subject < el2^.subject
  235.     end ; {compare}
  236.  
  237. procedure swap(var el1,el2 : pointer) ;
  238. {swap two entries pointed to by el1, el2}
  239.     var
  240.     temporary : pointer ;
  241.     begin
  242.     temporary := el1 ;
  243.     el1 := el2 ;
  244.     el2 := temporary
  245.     end {swap} ;
  246.  
  247.  
  248. procedure split(    var splitee    :table_type;
  249.             low,high    :integer;
  250.             var midindex    :integer) ;
  251.     var
  252.     middle : pointer ;
  253.     flag,up,down : integer ;
  254.     begin
  255.     up := low ;
  256.     down := high+1 ;
  257.     middle := splitee[low];    {split from first entry}
  258.     flag := 1 ;
  259.     while up < down do
  260.         if flag = 1
  261.         then {search downwards for a wrong one}
  262.            begin
  263.             down := down-1 ;
  264.             if (up<>down) and not lessthan(middle,splitee[down])
  265.                 then
  266.                 begin
  267.                     flag := 0 ;
  268.                     splitee[up] := splitee[down]
  269.                 end {THEN it's out of place}
  270.             end {THEN try and find a wrong one down}
  271.         else {search upwards for a wrong one}
  272.             begin
  273.             up := up + 1 ;
  274.             if (up <> down) and lessthan(middle,splitee[up])
  275.                 then
  276.                 begin
  277.                     flag := 1 ;
  278.                     splitee[down] := splitee[up]
  279.                 end {THEN it's out of place}
  280.             end {ELSE try finding a wrong one upwards};
  281.     splitee[up] := middle ;    {fit splitting element back}
  282.     midindex := up ;    {where it was split}
  283.     end ; {split}
  284.  
  285. procedure quicksort(var sortee: table_type; lower,upper:integer) ;
  286.     var
  287.     centre : integer ;
  288.     begin
  289.     if lower < upper
  290.         then
  291.         begin
  292.             split(sortee,lower,upper,centre) ;
  293.             quicksort(sortee,lower,centre-1) ;
  294.             quicksort(sortee,centre+1,upper)
  295.         end {then}
  296.     end; {quicksort}
  297.  
  298. procedure writeentry(var outfile:text; item : entry_type) ;
  299.  
  300.     var
  301.     j : integer ;
  302.  
  303.     begin
  304.     with item do
  305.         begin
  306.         write(outfile,subject) ;
  307.         if n_mains <> 0
  308.             then
  309.             begin
  310.                 write(outfile,chr(bold_code)) ;
  311.                 write(outfile,mains[1]:1) ;
  312.                 for j := 2 to n_mains do
  313.                 write(outfile,',',mains[j]:1) ;
  314.                 write(outfile,chr(bold_code)) ;
  315.                 if n_subs <> 0
  316.                 then write(outfile,',')
  317.             end ; {then}
  318.         if n_subs <> 0
  319.             then
  320.             begin
  321.                 write(outfile,subs[1]:1) ;
  322.                 for j := 2 to n_subs do
  323.                 write(outfile,',',subs[j]:1)
  324.             end ; { then }
  325.         writeln(outfile)
  326.         end {with}
  327.     end ; {writeentry}
  328.  
  329.  
  330. procedure help;
  331.  
  332.     var
  333.     null_line : string ;
  334.     begin
  335.     writeln(' This program generates a WordStar source') ;
  336.     writeln('file of an index for manuals, etc.') ;
  337.     writeln(' The index can be compiled from many files') ;
  338.     writeln('which may be scanned at different times.') ;
  339.     writeln(' The cumulative index file is stored in a') ;
  340.     writeln('file called "index" and is updated after') ;
  341.     writeln('each run of this program, so ERAse it when') ;
  342.     writeln('you want to restart the index compilation') ;
  343.     writeln(' The input files you are prompted for MUST') ;
  344.     writeln('be "DISK FILE OUTPUT"s from the WordStar') ;
  345.     writeln('Print command, with the FORMFEED option') ;
  346.     writeln(' The output file is WordStar compatible,') ;
  347.     writeln('and may be ^K Read into an index framework');
  348.     write('Press return') ; read (null_line) ;
  349.     writeln(' To mark an item for inclusion as one of');
  350.     writeln('the main references, use ^KQ.') ;
  351.     writeln(' To mark a minor reference, use ^KW') ;
  352.     writeln(' These markers must SURROUND the reference');
  353.     writeln('as for underlining.') ;
  354.     writeln(' The main references are listed first in');
  355.     writeln('BOLD type, and the minors after that in') ;
  356.     writeln('normal type') ;
  357.     writeln(' All marked text is converted to UPPER case');
  358.     writeln('The max. number of references per subject');
  359.     writeln('is ',max_refs,', and the maximum number of');
  360.     writeln('subjects is ',max_entries)
  361.     end ; {help}
  362.  
  363.  
  364. begin {main program}
  365.  
  366.     assign(index,'index') ;
  367.  
  368. { read in as much of the index as has been done already }
  369.     num_entries := 0 ;
  370.     reset(index) ;
  371.     if ioresult <> 255
  372.     then
  373.         begin
  374.         while (index^.n_mains<>-1) and not eof(index)do
  375.             begin
  376.             addentry(table,num_entries,index^) ;
  377.             get(index)
  378.             end {while}
  379.         end ; {then}
  380.     writeln(num_entries,' entries read from old index file');
  381.  
  382. { read in the new WordStar source files to be scanned }
  383.     repeat
  384.     writeln('Enter name of WordStar print file, or CR to continue') ;
  385.     read(filename) ;
  386.     if filename <> ''
  387.         then
  388.         if (filename = 'help') or (filename = 'HELP')
  389.             then help
  390.             else scanfile(table,num_entries,filename)
  391.     until filename = '' ;
  392.  
  393. { sort the new index }
  394.     quicksort(table,1,num_entries) ;
  395.  
  396. { save the new index }
  397.     rewrite(index) ;
  398.     if ioresult = 255
  399.     then writeln('Could not update index file')
  400.     else
  401.         begin
  402. { write index to the file }
  403.         for i := 1 to num_entries do
  404.             write(index,table[i]^) ;
  405. { now add end of file mark with n_mains =-1 }
  406.         end_file.n_mains := -1 ;
  407.         write(index,end_file) ;
  408.  
  409.         close(index,result) ;
  410.         if ioresult = 255
  411.             then writeln('Could not close index file')
  412.             else writeln(num_entries,' entries written to index file')
  413.         end {else} ;
  414.  
  415. { ask if a WordStar output file is required yet }
  416.     write('Is a WordStar output file required yet (y/n) ? ') ;
  417.     read(response) ;
  418.     if (response[1] = 'y') or (response[1] = 'Y')
  419.     then
  420.         begin
  421.         write('What filename ? ') ;
  422.         read(filename) ;
  423.         assign(text_out,filename) ;
  424.         rewrite(text_out) ;
  425.         if ioresult = 255
  426.             then writeln('Could not create ',filename)
  427.             else
  428.             begin
  429.                 for i := 1 to num_entries do
  430.                 writeentry(text_out,table[i]^);
  431.                 close(text_out,result)
  432.             end {else}
  433.         end {then}
  434. end. {index}
  435.